<template>
  <div class="app-container">
    <!-- 左右布局 -->
    <div class="main-layout">
      <!-- 左侧布局 -->
      <div class="left-section">
        <!-- 上部：串口通信区 -->
        <div class="serial-panel">
          <h1>电子秤</h1>
          <div class="control-group">
            <button @click="connectPort" :disabled="isConnected">连接串口</button>
            <button @click="disconnectPort" :disabled="!isConnected">断开连接</button>
            <div class="input-box">
              <input
                ref="batchInput"
                v-model="inputData"
                placeholder="输入批次号"
                :disabled="!isConnected || isMeasuring"
              />
              <button @click="sendData" :disabled="!isConnected || isMeasuring">开始测量</button>
            </div>
          </div>
          <div class="data-display">
            <div class="action-buttons">
              <button 
                @click="saveData" 
                :disabled="!tableData.length || !isMeasuring"
                class="save-btn"
              >
                保存数据
              </button>
              <button @click="clearOutput" :disabled="!isMeasuring">清空数据</button>
              <button @click="deleteSelectedData" :disabled="selectedRowIndex === -1 || !isMeasuring">删除选定数据</button>
            </div>
            <pre :class="{ 'disabled': !isMeasuring }">{{ outputData }}</pre>
          </div>
        </div>
        <!-- 下部：数据可视化区 -->
        <div class="chart-section">      
          <div class="chart-container" ref="chartContainer"></div>
        </div>
      </div>
      <!-- 右侧：数据表格区 -->
      <div class="right-panel">
        <h2>数据表格</h2>
        <div class="table-container">
          <table>
            <thead>
              <tr>
                <th>序号</th>
                <th>数据内容</th>
                <th>时间</th>
              </tr>
            </thead>
            <tbody>
              <tr 
                v-for="(item, index) in tableData" 
                :key="index"
                :class="{ 'selected': selectedRowIndex === index }"
                @click="selectRow(index)"
              >
                <td>{{ index + 1 }}</td>
                <td>{{ item.data }}</td>
                <td>{{ item.timestamp }}</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import * as echarts from 'echarts';
import { ref, defineComponent, onMounted, onBeforeUnmount } from "vue";

export default defineComponent({
  setup() {
    // 串口通信数据
    const port = ref(null);
    const isConnected = ref(false);
    const isMeasuring = ref(false);
    const inputData = ref("");
    const outputData = ref("");
    const buffer = ref("");
    const tableData = ref([]);
    const selectedRowIndex = ref(-1); // 选中行的索引
    const reader = ref(null); // 保存reader引用
    const isReading = ref(false); // 控制读取循环的标志
    const baogong_state = ref(false);
    const max_value =ref(0);
    const min_value =ref(0);
    const order_name_id =ref(0);
    const inspector_id =ref(0);
    const mes_old_data_id =ref(0);
    
    // 图表数据
    const chartType = ref("line");
    const chartInstance = ref(null);
    const chartData = ref({
      categories: [],
      values: [],
      values2: [],
      values3: []
    });
    
    // 串口通信方法
    const connectPort = async () => {
      if (!("serial" in navigator)) {
        alert("浏览器不支持Web Serial API");
        return;
      }
      try {
        port.value = await navigator.serial.requestPort();
        await port.value.open({ baudRate: 9600 });
        isConnected.value = true;
        isReading.value = true; // 开始读取
        readData();
      } catch (error) {
        alert("连接失败: " + error.message);
      }
    };

    const disconnectPort = async () => {
      if (!port.value) return;
      
      try {
        // 停止读取
        isReading.value = false;
        
        // 使用临时变量保存reader引用
        const tempReader = reader.value;
        reader.value = null; // 立即清空引用
        
        if (tempReader) {
          await tempReader.cancel(); // 取消读取
          tempReader.releaseLock(); // 释放锁
        }
        
        // 关闭串口
        await port.value.close();
        isConnected.value = false;
        isMeasuring.value = false;
        port.value = null;
        selectedRowIndex.value = -1; // 重置选中行
      } catch (error) {
        alert("断开连接失败: " + error.message);
        console.error("断开连接错误:", error);
      }
    };

    const sendData = async () => {
      if (!port.value || !isConnected.value) return;

      const order_name = inputData.value;
      if (order_name.includes("@")) {
          alert("有@!!!")
          baogong_state.value = false
          this.$refs.batchInput.style.backgroundColor = "red"
          if (this.inputData.trim()) {
              this.isMeasuring = true;
              // this.$refs.dataInput.focus();
          }
          console.log("this.max_value")
          console.log(this.max_value)
          setMaxMinValues_weibaog();
      } else {
        alert("没有@！！！")
      }
      
      // try {
      //   isMeasuring.value = true;
        
      //   // 发送数据
      //   const writer = port.value.writable.getWriter();
      //   const encoder = new TextEncoder();
      //   await writer.write(encoder.encode(inputData.value + '\n'));
      //   writer.releaseLock(); // 释放写锁
      // } catch (error) {
      //   console.error("发送错误:", error);
      //   isMeasuring.value = false;
      // }
    };

    const setMaxMinValues = (result_final) => {
            if (result_final["value_max"] === 0 || result_final["value_min"] === false) {
                if (result_final["value_min"] !== 0) {
                    this.max_value = 1000
                    this.min_value = result_final["value_min"]
                } else {
                    this.max_value = 0
                    this.min_value = 0
                }
            } else if (result_final["value_max"] === 0 && result_final["value_min"] === 0) {
                this.max_value = result_final["value_max"]
                this.min_value = result_final["value_min"]
            } else if (result_final["value_max"] === false && result_final["value_min"] === false) {
                this.max_value = 0
                this.min_value = 0
            } else {
                this.max_value = result_final["value_max"]
                this.min_value = result_final["value_min"]
            }
        };

    const readData = async () => {
      if (!port.value || !port.value.readable) return;
      
      try {
        reader.value = port.value.readable.getReader(); // 保存reader引用
        const decoder = new TextDecoder();
        
        while (isReading.value) { // 使用标志控制循环
          const { value, done } = await reader.value.read();
          if (done || !isReading.value) break;
          
          buffer.value += decoder.decode(value, { stream: true });
          const lines = buffer.value.split("\n");
          
          if (lines.length > 1) {
            for (let i = 0; i < lines.length - 1; i++) {
              const data = lines[i].trim();
              if (data) {
                outputData.value += data + "\n";
                tableData.value.push({
                  data: data,
                  timestamp: new Date().toLocaleString()
                });
                const numData = parseFloat(data) || 0;
                chartData.value.categories.push(new Date().toLocaleString());
                chartData.value.values.push(numData);
                chartData.value.values2.push(numData * 1.1);
                chartData.value.values3.push(numData * 0.9);
                updateChartData();
              }
            }
            buffer.value = lines[lines.length - 1];
          }
        }
      } catch (error) {
        if (error.name !== 'AbortError') { // 忽略主动取消的错误
          console.error("读取错误:", error);
          isMeasuring.value = false;
        }
      } finally {
        // 清理资源
        isReading.value = false;
        
        // 使用临时变量避免竞态条件
        const tempReader = reader.value;
        reader.value = null;
        
        if (tempReader) {
          tempReader.releaseLock();
        }
      }
    };

    const updateChartData = () => {
      if (chartInstance.value) {
        generateChart();
      }
    };

    // 图表方法
    const generateChart = () => {
      if (!chartInstance.value) {
        chartInstance.value = echarts.init(document.querySelector('.chart-container'));
      }
      
      const option = {
        title: { text: "数据统计分析" },
        tooltip: {},
        legend: {
          data: ['测量数据', '最大值', '最小值']
        },
        xAxis: { data: chartData.value.categories },
        yAxis: {},
        series: [
          {
            name: '测量数据',
            type: chartType.value,
            data: chartData.value.values,
            itemStyle: {
              color: '#5470C6'
            }
          },
          {
            name: '最大值',
            type: chartType.value,
            data: chartData.value.values2,
            itemStyle: {
              color: '#91CC75'
            }
          },
          {
            name: '最小值',
            type: chartType.value,
            data: chartData.value.values3,
            itemStyle: {
              color: '#EE6666'
            }
          }
        ]
      };
      
      chartInstance.value.setOption(option);
      window.addEventListener('resize', () => {
        if (chartInstance.value) {
          chartInstance.value.resize();
        }
      });
    };

    // 通用方法
    const saveData = () => {
      const blob = new Blob([JSON.stringify(tableData.value, null, 2)], 
        { type: "application/json" });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `serial-data-${new Date().toISOString().slice(0,10)}.json`;
      a.click();
      URL.revokeObjectURL(url);
    };
    const setMaxMinValues_weibaog = () => {
            this.max_value = 0
            this.min_value = 0
        }
        
    const clearOutput = () => {
      outputData.value = "";
      tableData.value = [];
      selectedRowIndex.value = -1; // 重置选中行
      chartData.value.categories = [];
      chartData.value.values = [];
      chartData.value.values2 = [];
      chartData.value.values3 = [];
      isMeasuring.value = false; // 停止测量状态
      if (chartInstance.value) {
        generateChart();
      }
    };

    const selectRow = (index) => {
      if (!isMeasuring.value) return; // 不在测量状态时不能选择行
      selectedRowIndex.value = index;
    };

    const deleteSelectedData = () => {
      if (selectedRowIndex.value !== -1 && tableData.value.length > 0) {
        tableData.value.splice(selectedRowIndex.value, 1);
        chartData.value.categories.splice(selectedRowIndex.value, 1);
        chartData.value.values.splice(selectedRowIndex.value, 1);
        chartData.value.values2.splice(selectedRowIndex.value, 1);
        chartData.value.values3.splice(selectedRowIndex.value, 1);
        selectedRowIndex.value = -1; // 重置选中行
        updateChartData();
      }
    };

    // 生命周期钩子
    onMounted(() => {
      generateChart();
    });

    onBeforeUnmount(() => {
      // 组件卸载前清理资源
      disconnectPort();
      
      if (chartInstance.value) {
        chartInstance.value.dispose();
        window.removeEventListener('resize', () => {
          if (chartInstance.value) {
            chartInstance.value.resize();
          }
        });
      }
    });

    return {
      // 数据
      isConnected,
      isMeasuring,
      inputData,
      outputData,
      tableData,
      selectedRowIndex,
      baogong_state: false,
      max_value: 0,
      min_value: 0,
      order_name_id:0,
      inspector_id:0,
      mes_old_data_id:[],
      
      // 方法
      connectPort,
      disconnectPort,
      sendData,
      saveData,
      clearOutput,
      selectRow,
      deleteSelectedData
    };
  }
});
</script>

<style>
.app-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  padding: 20px;
  background: #f5f7fa;
}

.main-layout {
  display: flex;
  gap: 20px;
  height: 100%;
}

.left-section {
  flex: 2;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.serial-panel {
  flex: 1;
  background: white;
  border-radius: 8px;
  padding: 15px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  display: flex;
  flex-direction: column;
}

.chart-section {
  flex: 1;
  background: white;
  border-radius: 8px;
  padding: 15px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}

.right-panel {
  flex: 1;
  background: white;
  border-radius: 8px;
  padding: 15px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  display: flex;
  flex-direction: column;
}

h1, h2 {
  color: #333;
  margin-bottom: 15px;
}

.control-group, .query-controls, .chart-controls {
  display: flex;
  gap: 10px;
  margin-bottom: 15px;
}

.input-box {
  display: flex;
  flex: 1;
  gap: 10px;
}

input, select {
  flex: 1;
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

button {
  padding: 8px 15px;
  border: none;
  border-radius: 4px;
  background: #409EFF;
  color: white;
  cursor: pointer;
  transition: background 0.3s;
}

button:hover {
  background: #66b1ff;
}

button:disabled {
  background: #c0c4cc;
  cursor: not-allowed;
}

.save-btn {
  background: #67C23A;
}

.save-btn:hover {
  background: #85ce61;
}

.action-buttons {
  display: flex;
  gap: 10px;
  margin-bottom: 10px;
}

.data-display pre {
  background: #f9f9f9;
  padding: 10px;
  border-radius: 4px;
  height: 150px;
  overflow: auto;
  font-family: monospace;
  opacity: 0.5;
  cursor: not-allowed;
}

.data-display pre:not(.disabled) {
  opacity: 1;
  cursor: auto;
}

.table-container {
  flex: 1;
  overflow: auto;
}

table {
  width: 100%;
  border-collapse: collapse;
}

th, td {
  padding: 12px 15px;
  border: 1px solid #ebeef5;
  text-align: left;
}

th {
  background: #f5f7fa;
  position: sticky;
  top: 0;
}

tr:hover {
  background: #f0f2f5;
}

tr.selected {
  background: #e6f7ff;
}

.chart-container {
  width: 100%;
  height: calc(100% - 60px);
  min-height: 300px;
}
</style>    